home *** CD-ROM | disk | FTP | other *** search
/ BBS Toolkit / BBS Toolkit.iso / doors_1 / doorskl3.zip / SAMPLE.C < prev    next >
C/C++ Source or Header  |  1991-12-15  |  12KB  |  345 lines

  1. /*
  2.  *
  3.  * Sample door created with DOORSKEL.LZH archive
  4.  *
  5.  */
  6.  
  7. #include "doorskel.h"
  8.  
  9. static void _fastcall calendar (void);
  10. static int  _fastcall dayno(int yyyy, int mm, int x, int y);
  11. static void _fastcall prt3mon(int yr, int a, char *prtmon);
  12. int         _fastcall print_amonth (int yr, int month);
  13. static void _fastcall moontxt (void);
  14.  
  15.  
  16.  
  17.  
  18. void _fastcall mainloop (void) {
  19.  
  20.   static char *options[] = {"Calendar","Moon Phase","Quit"};
  21.   #define NUMSELECTS 3
  22.   static char *prompt = "\r\nChoose: ";
  23.   int         com;
  24.  
  25.  
  26.   cls();
  27.  
  28.   for(;;) {
  29.     carrchk();
  30.     getxbbstime();
  31.     if(!graphics) {
  32.         com = select_one(options,NUMSELECTS,prompt,1);
  33.     }
  34.     else {
  35.         printm("\x1b[s\x1b[2;1H\x1b[K\x1b[u");
  36.         com = top_menu(options,NUMSELECTS);
  37.     }
  38.  
  39.     switch(com) {
  40.         case -1:    break;
  41.  
  42.         case 0:     calendar();
  43.                     break;
  44.  
  45.         case 1:     moontxt();
  46.                     break;
  47.  
  48.         case NUMSELECTS - 1:    /* quit */
  49.                     return;
  50.                     break;
  51.  
  52.         default:    printm("\r\nNot yet implemented.\r\n");
  53.                     break;
  54.     }
  55.   }
  56. }
  57.  
  58.  
  59.  
  60. /*********************************************************************/
  61. /*                                                                   */
  62. /*  This Program Written by Paul Edwards.                            */
  63. /*                                                                   */
  64. /*  (Modified very slightly to work as a door by M. Kimes)           */
  65. /*  This module would replace DOORSKL4.C to create a working door.   */
  66. /*                                                                   */
  67. /*  The following block of notes are Paul's.                         */
  68. /*                                                                   */
  69. /*********************************************************************/
  70. /*********************************************************************/
  71. /*                                                                   */
  72. /*  Calendar - produce a calendar for any given year.                */
  73. /*                                                                   */
  74. /*  This program takes as a command line parameter a single number   */
  75. /*  which should be a 4 digit year.  It then prints out a calendar   */
  76. /*  corresponding to that year.  This program was inspired by a      */
  77. /*  shareware program which performed a similar function but didn't  */
  78. /*  come with source!                                                */
  79. /*                                                                   */
  80. /*  Many many thanks to Paul Schlyter, Stockholm, Sweden for his     */
  81. /*  absolutely fantastically brilliant dow macro.  However, due to   */
  82. /*  limitations of this macro (which are affected by anomolies of    */
  83. /*  the '/' and '%' operators on negative numbers) this program will */
  84. /*  generate invalid calendars for years such as 4 AD.  But I reckon */
  85. /*  anyone who wants to print out the gregorian calendar for 4 AD is */
  86. /*  a total wanker, especially when you consider the fact that the   */
  87. /*  gregorian calendar only came into existence in 1582.  There is   */
  88. /*  no upper limit to the year the calendar can print.  The program  */
  89. /*  also knows all the rules, ie the 4, 100, 400 year rules for a    */
  90. /*  leapyear, so that even if you don't know that 1900 wasn't a      */
  91. /*  leapyear, yet 2000 will be, this program knows!  Oh yeah, I'm    */
  92. /*  not sure exactly where the lower bound on calendars is, but it   */
  93. /*  will certainly work for anything above 1582.  Have fun!  Paul.   */
  94. /*                                                                   */
  95. /*  This program is dedicated to the public domain.                  */
  96. /*                                                                   */
  97. /*  Written 1990/8/28.                                               */
  98. /*                                                                   */
  99. /*********************************************************************/
  100.  
  101.  
  102. static void _fastcall calendar (void) {
  103.  
  104.     int yr, wrkyr, dig1, dig2, dig3, dig4;
  105.     char yrstr[32];
  106.  
  107.  
  108.     printm("\r\nYear for calendar? ");
  109.     strcpy(yrstr,genin(5,0,0,0,NUM));
  110.     printm("\r\n");
  111.     if(!*yrstr) return;
  112.  
  113.     yr = atoi(yrstr);
  114.  
  115.     wrkyr = yr;
  116.     dig1 = wrkyr / 1000;
  117.     wrkyr %= 1000;
  118.     dig2 = wrkyr / 100;
  119.     wrkyr %= 100;
  120.     dig3 = wrkyr / 10;
  121.     wrkyr %= 10;
  122.     dig4 = wrkyr;
  123.     printfm("\r\n                                %d %d %d %d\r\n\r\n",
  124.             dig1,dig2,dig3,dig4);
  125.     prt3mon(yr, 0, "       JANUARY                 FEBRUARY"
  126.             "                   MARCH");
  127.     prt3mon(yr, 1, "        APRIL                     MAY"
  128.             "                     JUNE");
  129.     prt3mon(yr, 2, "        JULY                    AUGUST"
  130.             "                  SEPTEMBER");
  131.     prt3mon(yr, 3, "       OCTOBER                 NOVEMBER"
  132.             "                 DECEMBER");
  133. }
  134.  
  135.  
  136.  
  137.  
  138. static void _fastcall prt3mon (int yr, int a, char *prtmon) {
  139.  
  140.   /* print 3 months */
  141.  
  142.   static char *letters = " s  m  t  w  t  f  s     "
  143.                          " s  m  t  w  t  f  s     "
  144.                          " s  m  t  w  t  f  s\r\n";
  145.   int b, i, j, x;
  146.  
  147.  
  148.   printfm("%s\r\n\r\n",prtmon);
  149.   printfm("%s",letters);
  150.   for(i = 0;i < 6;i++) {
  151.     for(b = 1;b <= 3;b++) {
  152.       for(j = 0;j < 7;j++) {
  153.         x = dayno(yr,a * 3 + b,i,j);
  154.         if(x) printfm("%2d ",x);
  155.         else printfm("   ");
  156.       }
  157.       printfm("    ");
  158.     }
  159.     printfm("\r\n");
  160.   }
  161.   return;
  162. }
  163.  
  164.  
  165.  
  166.  
  167. int _fastcall print_amonth (int yr, int month) {
  168.  
  169.     /* print an individual month...not used in this module... */
  170.  
  171.   int wrkyr, dig1, dig2, dig3, dig4;
  172.   char *mons[] = {"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG",
  173.                   "SEP","OCT","NOV","DEC"};
  174.   char *letters = " s  m  t  w  t  f  s\r\n";
  175.   int i, j, x;
  176.  
  177.  
  178.   wrkyr = yr;
  179.   dig1 = wrkyr / 1000;
  180.   wrkyr %= 1000;
  181.   dig2 = wrkyr / 100;
  182.   wrkyr %= 100;
  183.   dig3 = wrkyr / 10;
  184.   wrkyr %= 10;
  185.   dig4 = wrkyr;
  186.   printfm("\r\n     %d %d %d %d\r\n\r\n",
  187.       dig1,dig2,dig3,dig4);
  188.  
  189.   printfm("       %s\r\n",mons[month-1]);
  190.   printfm("%s",letters);
  191.   for(i = 0;i < 6;i++) {
  192.       for(j = 0;j < 7;j++) {
  193.         x = dayno(yr,month,i,j);
  194.         if (x) printfm("%2d ",x);
  195.         else printfm("   ");
  196.       }
  197.       printfm("\r\n");
  198.   }
  199.   printfm("\r\n");
  200.   return 0;
  201. }
  202.  
  203.  
  204. #define isleap(year) ((((year % 4) == 0) && ((year % 100) != 0)) || \
  205.     ((year % 400) == 0))
  206.  
  207.  
  208. #define dow(y,m,d)  \
  209. ( ( ( 3 * (y) - (7 * ((y) + ((m) + 9) / 12)) / 4 + (23 * (m)) / 9 + (d) + 2 \
  210.     + (((y) - ((m) < 3)) / 100 + 1) * 3 / 4 - 15 ) % 7 ) )
  211.  
  212.  
  213.  
  214.   static int daytab[] = { 31, 28, 31, 30, 31, 30,
  215.                           31, 31, 30, 31, 30, 31};
  216.  
  217.  
  218. static int _fastcall dayno (int yyyy, int mm, int x, int y) {
  219.  
  220.   int a, b, c;
  221.  
  222.  
  223.   a = dow(yyyy,mm,1);
  224.   b = x * 7 + y;
  225.   c = daytab[mm - 1];
  226.   if ((mm == 2) && isleap(yyyy)) c++;
  227.   if (b < a) return (0);
  228.   if ((b - a) >= c) return (0);
  229.   return ((b - a + 1));
  230. }
  231.  
  232.  
  233.  
  234. /* =-=-=-=-=-From BSD Unix with modification by Lynn Nash-=-=-=-=-=-=
  235.              further hacked by M. Kimes to work in a door
  236.              the following block of notes are Lynn's (or from BSD):
  237.  * Output the phase of the moon for the given year, month, day.
  238.  * The routine calculates the year's epact (the age of the moon on
  239.  * Jan 1.), adds this to the number of days in the year, and
  240.  * calculates the phase of the moon for this date.
  241.  * In the algorithm:
  242.  *  diy    Is the day of the year - 1 (i.e., Jan 1 is day 0).
  243.  *  golden Is the number of the year in the Mentonic cycle, used to
  244.  *         determine the position of the calender moon.
  245.  *  epact  Is the age of the calender moon (in days) at the beginning
  246.  *         of the year.  To calculate epact, two century-based
  247.  *         corrections are applied:
  248.  *           Gregorian:      (3 * cent)/4 - 12
  249.  *                   is the number of years such as 1700, 1800 when
  250.  *                   leap year was not held.
  251.  *           Clavian:        (((8 * cent) + 5) / 25) - 5
  252.  *                   is a correction to the Mentonic cycle of about
  253.  *                   8 days evry 2500 years.  Note that this will
  254.  *                   overflow 16 bits in the year 409600.  Beware.
  255.  * The algorithm is accurate for the Gregorian calender only.
  256.  * The magic numbers used in the phase calculation are as follows:
  257.  *     29.5    The moon's period in days.
  258.  *    177      29.5 scaled by 6
  259.  *     22      (29.5 / 8) scaled by 6 (this gets the phase)
  260.  *     11      ((29.5 / 8) / 2) scaled by 6
  261.  * Theoretically, this should yield a number in the range 0 .. 7.
  262.  * However, two days per year, things don't work out too well.
  263.  * Epact is calculated by the algorithm given in Knuth vol. 1
  264.  * (calculation of Easter).  See also the article on Calenders in
  265.  * the Encyclopaedia Britannica and Knuth's algorithm in CACM April
  266.  * 1962, page 209.
  267.  */
  268.  
  269. static char *phasetxt[] = {
  270.   "new",                   /* totally dark                         */
  271.   "waxing crescent",       /* increasing to full & quarter light   */
  272.   "first quarter",         /* increasing to full & half light      */
  273.   "waxing gibbous",        /* increasing to full & > than half     */
  274.   "full",                  /* fully lighted                        */
  275.   "waning gibbous",        /* decreasing from full & > than half   */
  276.   "last quarter",          /* decreasing from full & half light    */
  277.   "waning crescent"        /* decreasing from full & quarter light */
  278. };
  279.  
  280. static int day_year[] = {  /* Days in year for each month       */
  281.   -1, -1, 30, 58, 89, 119, 150, 180, 211, 241, 272, 303, 333
  282. };                        /* Note: Jan. 1 will equal zero      */
  283.  
  284.  
  285. static void _fastcall moontxt (void) {
  286.  
  287.   int  year;           /* 1978 = 1978 */
  288.   int  month;          /* Jan = 1 */
  289.   int  day;            /* 1 = 1 */
  290.   int  phase;          /* Moon phase                  */
  291.   int  cent;           /* Century number (1979 = 20)  */
  292.   int  epact;          /* Age of the moon on Jan. 1   */
  293.   int  diy;            /* Day in the year             */
  294.   int  golden;         /* Moon's golden number        */
  295.   char yrstr[32],was;
  296.   int  c;
  297.  
  298.  
  299.   printm("\r\nDate for moon phase? ");
  300.   strcpy(yrstr,genin(8,0,0,0,DATE));
  301.   printm("\r\n");
  302.   if(strlen(yrstr) < 8) {
  303.  
  304. Invalid:
  305.  
  306.     printm("Invalid date.\r\n");
  307.     return;
  308.   }
  309.  
  310.   was = yrstr[4];
  311.   yrstr[4] = 0;
  312.   year = atoi(yrstr);
  313.   yrstr[4] = was;
  314.   was = yrstr[6];
  315.   yrstr[6] = 0;
  316.   month = atoi(&yrstr[4]);
  317.   yrstr[6] = was;
  318.   day = atoi(&yrstr[6]);
  319.  
  320.   if (month < 1 || month > 12) goto Invalid;
  321.   c = daytab[month - 1];
  322.   if ((month == 2) && isleap(year)) c++;
  323.   if(day < 1 || day > c) goto Invalid;
  324.  
  325.   diy = day + day_year[month];            /* Day in the year  */
  326.   if (month > 2 && isleap(year))
  327.     diy++;                                /* Leapyear fixup       */
  328.   cent = (year / 100) + 1;                /* Century number       */
  329.   golden = (year % 19) + 1;               /* Golden number        */
  330.   epact = ((11 * golden) + 20             /* Golden number        */
  331.      + (((8 * cent) + 5) / 25) - 5        /* 400 year cycle       */
  332.      - (((3 * cent) / 4) - 12)) % 30;     /* Leap year correction */
  333.   if (epact <= 0)
  334.     epact += 30;                          /* Age range is 1 .. 30 */
  335.   if ((epact == 25 && golden > 11) || epact == 24)
  336.     epact++;
  337.   /*
  338.    * Calculate the phase, using the magic numbers defined above.
  339.    * Note that (phase and 7) is equivalent to (phase mod 8) and
  340.    * is needed on two days per year (when the algorithm yields 8).
  341.    */
  342.   phase = (((((diy + epact) * 6) + 11) % 177) / 22) & 7;
  343.   printfm("\r\nPhase of the moon: %s\r\n",phasetxt[phase]);
  344. }
  345.